package com.setoption.service;

import com.setoption.entity.SetClassroomResult;
import com.setoption.entity.SetClassroomSurplus;
import com.setoption.entity.Term;
import com.setoption.enums.ExceptionEnums;
import com.setoption.exception.MyException;
import com.setoption.mapper.CourseArrangementMapper;
import com.setoption.pojo.Classroom;
import com.setoption.pojo.CourseArrangement;
import com.setoption.pojo.CourseInfo;
import com.setoption.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;

@Service
public class ClassroomSetService {

    @Resource
    private CourseArrangementMapper courseArrangementMapper;
    @Resource
    private ClassroomManagerService classroomManagerService;
    @Resource
    private CourseSelectionService courseSelectionService;
    @Resource
    private CourseInfoService courseInfoService;
    @Value("${myconfig.filepath}")
    private File systemSetting;
    @Resource
    private JsonUtils jsonUtils;

    private Map<String, List<Classroom>> classroomClassify(List<Classroom> list) {
        List<Classroom> bigneed = new ArrayList<>();
        List<Classroom> bigno = new ArrayList<>();
        List<Classroom> medineed = new ArrayList<>();
        List<Classroom> medino = new ArrayList<>();
        List<Classroom> smallneed = new ArrayList<>();
        List<Classroom> smallno = new ArrayList<>();
        for (Classroom classroom : list) {
            int people = classroom.getClassroomCapacity();
            boolean need = classroom.getClassroomMutil();
            if (people > 60) {
                if (need) bigneed.add(classroom);
                else bigno.add(classroom);
            } else {
                if (people > 30) {
                    if (need) medineed.add(classroom);
                    else medino.add(classroom);
                } else {
                    if (need) smallneed.add(classroom);
                    else smallno.add(classroom);
                }
            }
        }
        Map<String, List<Classroom>> map = new HashMap<>();
        map.put("bigneed", bigneed);
        map.put("bigno", bigno);
        map.put("medineed", medineed);
        map.put("medino", medino);
        map.put("smallneed", smallneed);
        map.put("smallno", smallno);
        return map;
    }

    private Map<String, List<CourseInfo>> courseClassify(List<CourseInfo> list) {
        List<CourseInfo> bigneed = new ArrayList<>();
        List<CourseInfo> bigno = new ArrayList<>();
        List<CourseInfo> medineed = new ArrayList<>();
        List<CourseInfo> medino = new ArrayList<>();
        List<CourseInfo> smallneed = new ArrayList<>();
        List<CourseInfo> smallno = new ArrayList<>();
        for (CourseInfo courseInfo : list) {
            int people = courseSelectionService.getCourseSelectionSum(courseInfo.getCourseNo());
            boolean need = courseInfo.getCourseMultimedia();
            if (people > 60) {
                if (need) bigneed.add(courseInfo);
                else bigno.add(courseInfo);
            } else {
                if (people > 30) {
                    if (need) medineed.add(courseInfo);
                    else medino.add(courseInfo);
                } else if(people!=0){
                    if (need) smallneed.add(courseInfo);
                    else smallno.add(courseInfo);
                }
            }
        }
        Map<String, List<CourseInfo>> map = new HashMap<>();
        map.put("bigneed", bigneed);
        map.put("bigno", bigno);
        map.put("medineed", medineed);
        map.put("medino", medino);
        map.put("smallneed", smallneed);
        map.put("smallno", smallno);
        return map;
    }


    private Map<String, SetClassroomResult> setClassroomAndgetSurplus(Map<String, List<Classroom>> classroom, Map<String, List<CourseInfo>> courseinfos) {
        Map<String, SetClassroomResult> map = new HashMap<>();
        Term term = jsonUtils.readJson(systemSetting, Term.class);
        Boolean isnull = true;
        if (courseArrangementMapper.selectAllCourseArrangement(term.getYear(), term.getTerm()).size() != 0)
            isnull = false;
        map.put("bigneed", setClassroomToArrangement(classroom.get("bigneed"), courseinfos.get("bigneed"), isnull));
        map.put("mapbigno", setClassroomToArrangement(classroom.get("bigno"), courseinfos.get("bigno"), isnull));
        map.put("medineed", setClassroomToArrangement(classroom.get("medineed"), courseinfos.get("medineed"), isnull));
        map.put("medino", setClassroomToArrangement(classroom.get("medino"), courseinfos.get("medino"), isnull));
        map.put("smallneed", setClassroomToArrangement(classroom.get("smallneed"), courseinfos.get("smallneed"), isnull));
        map.put("smallno", setClassroomToArrangement(classroom.get("smallno"), courseinfos.get("smallno"), isnull));
        return map;

    }

    public Map<String, SetClassroomResult> setClassroom() {
        List<Classroom> classroomList = classroomManagerService.selectAllClassroom();
        List<CourseInfo> courseInfo = getCourseInfoList();
        Map<String, List<Classroom>> classroomClassifys = classroomClassify(classroomList);
        Map<String, List<CourseInfo>> courseArrangementClassifys = courseClassify(courseInfo);
        return setClassroomAndgetSurplus(classroomClassifys, courseArrangementClassifys);
    }

    public List<CourseInfo> getCourseInfoList() {
        return courseInfoService.getCourseList();
    }

    public SetClassroomResult setClassroomToArrangement(List<Classroom> classroom, List<CourseInfo> courseInfos, Boolean isnull) {
        int classroomLength = classroom.size();
        int courseInfoLength = courseInfos.size();
        SetClassroomSurplus setClassroomSurplus = new SetClassroomSurplus();
        if (classroomLength == 0 && courseInfoLength == 0) {
            setClassroomSurplus.setMessage("null");
            return new SetClassroomResult(null, setClassroomSurplus);
        } else if (classroomLength == 0) {
            setClassroomSurplus.setCourseInfos(courseInfos);
            setClassroomSurplus.setMessage("course");
            return new SetClassroomResult(null, setClassroomSurplus);
        } else if (courseInfoLength == 0) {

            Map<String, Integer> map = new HashMap<>();
            for (int i = 0; i < classroomLength; i++) {
                map.put("" + classroom.get(i).getClassroomNo(), 0);
            }
            setClassroomSurplus.setClassroom(map);
            setClassroomSurplus.setMessage("classroom");
            return new SetClassroomResult(null, setClassroomSurplus);
        }

        Collections.shuffle(classroom);
        Collections.shuffle(courseInfos);
        Map<String, List<CourseInfo>> mapca = new HashMap<>();
        for (int i = 0; i < classroomLength; i++) {
            mapca.put("" + classroom.get(i).getClassroomNo(), new LinkedList<CourseInfo>());
        }
        int CAcounter = courseInfoLength - 1;
        for (int i = 0; i < 25; i++) {
            for (int j = 0; j < classroomLength; j++) {
                mapca.get("" + classroom.get(j).getClassroomNo()).add(courseInfos.get(CAcounter));
                CAcounter--;
                if (CAcounter < 0) {
                    Map<String, Integer> map = new HashMap<>();
                    if (j + 1 > 0) {
                        for (int k = 0; k < j + 1; k++) {
                            map.put("" + classroom.get(k).getClassroomNo(), i + 1);
                        }
                    }
                    for (int k = j + 1; k < classroomLength; k++) {
                        map.put("" + classroom.get(k).getClassroomNo(), i);
                    }
                    setClassroomSurplus.setClassroom(map);
                    setClassroomSurplus.setMessage("classroom");
                    break;
                }
            }
            if (CAcounter < 0) break;
        }
        if (CAcounter >= 0) {
            setClassroomSurplus.setCourseInfos(courseInfos.subList(0, CAcounter + 1));
            setClassroomSurplus.setMessage("course");
        }
        List<CourseArrangement> courseArrangementList = new LinkedList<>();
        Map<String, List<CourseArrangement>> maprs = new HashMap<>();
        for (String s : mapca.keySet()) {
            List<CourseInfo> list = mapca.get(s);
            for (int i = 0; i < list.size(); i++) {
                CourseArrangement courseArrangement = new CourseArrangement();
                courseArrangement.setClassroomNumber(s);
                courseArrangement.setCourseTime(i + 1);
                courseArrangement.setCourseNum(list.get(i).getCourseNo());
                courseArrangement.setCourseClassno(list.get(i).getCourseObject());
                courseArrangementList.add(courseArrangement);
                maprs.put(s, courseArrangementList);
            }
            Term term = jsonUtils.readJson(systemSetting, Term.class);
            if (isnull)
                courseArrangementMapper.batchInsert(courseArrangementList, term.getYear(), term.getTerm());
        }

        return new SetClassroomResult(maprs, setClassroomSurplus);

    }

    public int createTable(Map<String, Object> map) {
        String year = String.valueOf(map.get("year"));
        String term = String.valueOf(map.get("term"));
        int result = courseArrangementMapper.createTable(year, term);
        return result;
    }

    public int fenpeiAganin(Map<String, Object> map) {
        Term term = jsonUtils.readJson(systemSetting, Term.class);
        Integer id = Integer.parseInt(map.get("id").toString());
        String classroomNumber = courseArrangementMapper.selectClassroomById(id, term.getYear(), term.getTerm()).getClassroomNumber();
        if (!(classroomNumber == null || classroomNumber.equals("")))
            return 0;
        String classroomNo = String.valueOf(map.get("classroomNo"));
        Integer courseTime = Integer.parseInt(map.get("courseTime").toString());
        return courseArrangementMapper.updateClassroomById(id, classroomNo, courseTime, term.getYear(), term.getTerm());
    }
}
